function varargout = TLTl2rtiDlg(varargin)

% Dialog function for tl_tl2rti block
%
% SYNTAX:
%
%   TLTl2rtiDlg('Create',hBlock) 
%      - create dialog window
%
%   TLTl2rtiDlg('closeDlg')
%      - close dialog window
%
%   userData = TLTl2rtiDlg('Sync',userData) 
%      - synchronize data callback when user changes an option
%
%   userData = TLTl2rtiDlg('Apply',userData)
%      - callback for Apply button
%
%   userData = TLTl2rtiDlg('Build',userData)
%      - callback for Build button
%
%   userData = TLTl2rtiDlg('Help',userData)
%      - callback for Help button
%
%   dataDescription = TLTl2rtiDlg('GetDataDescription')
%      - return the block data description
%
%
% The following data is stored with the block
%   blockData.revisionNumber          <integer>   - current revision number (for upgrading)
%   blockData.destinationModel        <string>    - destination model the generated stand-alone
%                                                   S-Function(s) are to be copied 
%   blockData.destinationDirectory    <string>    - directory where the destination model
%                                                   resides
%   blockData.tlSubsystems            <string>    - list of selected TL subsystems
%   blockData.enableDDCgUnitSelection [0 1]       - enable/disbale selection of the CodeGenerationUnits
%   blockData.ddCGUnits               <string>    - list of selected DD CodeGeneratorUnits
%   blockData.destinationBlockList    <string>    - list of destination block
%   blockData.generateTRC             [0 1]       - enable/disable TRC file generation
%   blockData.fixPointSupport         [0 1]       - enable/disbale fix point support of the TRC file generator
%   blockData.updateUserMakefile      [0 1]       - enable/disbale update of the RTI user makefile 
%   blockdata.generatePPCApplication  [0 1]       - enable/disbale generation of the RTI real-time application
%                                                   for the PPC processor board

% $Workfile: $ $Revision: 1.11 $ $Date: 2011/05/26 08:09:51MESZ $
% $Archive:  $
% author: R.Hein dSPACE GmbH

% default return value
varargout{1} = [];

% default input value
if isempty(varargin)
   varargin{1} = 'Create';
   varargin{2} = gcbh;
elseif nargin < 2
   varargin{2} = gcbh;
end

% get action string
action = varargin{1};
if ~ischar(action),
   ds_error_msg('Invalid action string.');
   return;
end


% perform selected action
switch(lower(action)),
   case 'create'
      % create the dialog window
      ds_error_none;
      FcnCreate(varargin{2});
      if ds_error_check, return; end
   case 'sync'
      % synchronize data after user input
      varargout{1} = FcnSync(varargin{2});
      if ds_error_check, return; end
  case 'help'
      % callback for Help button
      varargout{1} = FcnHelp(varargin{2});
      if ds_error_check, return; end
   case 'apply'
      % callback for Apply button
      varargout{1} = FcnApply(varargin{2});
      if ds_error_check, return; end
   case 'build'
      % callback for Build button
      varargout{1} = FcnBuild(varargin{2});
      if ds_error_check, return; end      
   case 'getdatadescription'
      % return the block data description
      varargout{1} = FcnGetDataDescription(varargin{2});
      if ds_error_check, return; end
   case 'closedlg'
      % close this dialog window
      FcnCloseDlg(varargin{2});
      if ds_error_check, return; end
   case 'browse'
      % pushbutton
      varargout{1} = FcnBrowse(varargin{2});
   otherwise
      ds_error_msg(['Invalid action string"',action,'"']);
      return;
end
   
   
%===========================================================================
% private function to close this dialog
%===========================================================================
function FcnCloseDlg(hBlock)

% get all open figures, also the hidden ones
tmp = get(0,'ShowHiddenHandles');
set(0,'ShowHiddenHandles','on');
allfigs = get(0,'Children');
set(0,'ShowHiddenHandles',tmp);

dlgfigs = findobj(allfigs,'Tag','#Fig_tl_tl2rti');
for i=1:length(dlgfigs),
   dlgUserData = get(dlgfigs(i),'UserData');
   if ~isstruct(dlgUserData)
      % dialog corrupt
      delete(dlgfigs(i));
   elseif dlgUserData.hBlock == hBlock,
      delete(dlgfigs(i));
   end
end


%===============================================================================
% private function to select the destination model's directory
%===============================================================================
function userData = FcnBrowse(userData)

% open the directory browser
[model, directory] = uigetfile('*.mdl','Select a model');
if ~isequal(model,0) && ~isequal(directory,0) 
    % a new model been selected
    % from the model name remove the extension
    [path, model]  = fileparts(model);
    uiCtrlDestDirectory = userData.dataDescription.destinationDirectory.uiControl;
    uiCtrlDestModel     = userData.dataDescription.destinationModel.uiControl;
    userData.uiControl(uiCtrlDestModel).value     = model;
    userData.uiControl(uiCtrlDestDirectory).value = directory(1:end-1);
    
    userData = FcnManageDestinationBlock(userData);
    
    % enable the Apply button
    hApply = userData.buttonData(4).handle;
    set(hApply, 'Enable','on');
end

userData.bApplyUiControls = 1;
userData.bApplyData       = 0;
userData.bClose           = 0;

%================================================================================
% private function to synchronize the data after an user input
%================================================================================

function userData = FcnSync(userData)

% return, if model does not contain any TL subsystem
if isempty(userData.dataDescription.tlSubsystems.defaultValue),
    return;
end

if userData.currentUiControl == 0,
    % Dialog is currently created
    
    % Check if destination model name and path are set
    % if not take the current model and current directory
    userData = FcnSetDestinationModel(userData);
 
    % Synchronize the values of selected TL Subsystems with the
    % currently in model available TL subsystems
    userData = FcnSyncTLSubsystems(userData); 
    
    % Synchronize the destination block list with in the model
    % currently available TargetLink subsystems
    userData = FcnSyncDestinationBlockList(userData);
    
    % if rti is not installed disable the generatePPCApplication uiControl
    generatePPCApplicationUiControl = userData.dataDescription.generatePPCApplication.uiControl;
    if exist('rtiver','file') ~= 2,
       userData.uiControl(generatePPCApplicationUiControl).bEnabled = 0;
   end
end


% check the consistency of the uiControls
% disable/enable controls depending of made settings
userData = FcnManageControlsConsistency(userData);


userData.bApplyUiControls = 1;
userData.bApplyData       = 0;
userData.bClose           = 0;


%================================================================================
% private function to manage the Help button
%================================================================================

function userData = FcnHelp(userData)

% Call the dSPACE online help
ds_open_help(mfilename);

userData.bApplyUiControls = 0;
userData.bApplyData       = 0;
userData.bClose           = 0;


%================================================================================
% private function to manage the Apply button
%================================================================================

function userData = FcnApply(userData)

userData.bApplyUiControls = 1;
userData.bApplyData       = 1;
userData.bClose           = 0;


%================================================================================
% private function to manage the Build button
%================================================================================

function userData = FcnBuild(userData)

% Before build write the data to the block
userData.bApplyUiControls = 1;
userData.bApplyData       = 1;

% First get the information from the userData
% dataDescription = FcnGetDataDescription(userData.hBlock);
% If dialog is open take the dataDescritpion from the userData !
% Otherwise the controls Ids may change if for example
% a new TL Subsystem has been added !
dataDescription = userData.dataDescription;


% then get the inputs for the tl_tl2rti function:

% source and destination model
srcModel      = bdroot(userData.hBlock);
destModel     = userData.uiControl(dataDescription.destinationModel.uiControl).value;
destDirectory = userData.uiControl(dataDescription.destinationDirectory.uiControl).value;

% check if destination directory exist
if ~exist(destDirectory,'dir'),
   ds_error_msg({...
      'The destination directory',...
      ['    ' destDirectory ],...
      'does not exist !'});
   return;
end

% check if destination model exist
destModelFullFileName = [destDirectory '' destModel '.mdl'];
if ~exist(destModelFullFileName,'file'),
   answer = ds_msgbox('Message',{ ...
      'The specified destination model',...
      ['      ' destModel], ...
      'does not exist in the destination directory.', ...
      'Thus it will be created as a copy of the source model', ...
      ['      ' get_param(srcModel,'Name')], ...
      '', ...
      'Do you wish to continue?',''}, ...
      'Title',   'Proceed and create new model?',...
      'Style',   'Question', ...
      'Button',  {'Continue','Abort'}, ...
      'Default', 'Continue', ...
      'Mode',    'modal');
   if strcmp(answer, 'Abort'),
      return;
   end
   % create the destination model
   srcFileName = get_param(srcModel, 'FileName');
   copyfile(srcFileName, destModelFullFileName);
end

% code generator options
if userData.uiControl(dataDescription.generateForIncrSubsystems.uiControl).value,
    generateAll = 'on';
else
    generateAll = 'off';
end

% frame options
if userData.uiControl(dataDescription.generateGlobalSymbols.uiControl).value,
    generateGlobalSymbols = 'on';
else
    generateGlobalSymbols = 'off';
end


% trc file options
trcFileHierarchy = 'subsystems';
generateTRC      = 'no';
fxpSupport       = 'no';
if userData.uiControl(dataDescription.generateTRC.uiControl).value,
    generateTRC = 'yes';
    if strcmp(userData.uiControl(dataDescription.trcFileHierarchy.uiControl).value, 'generated functions')
        trcFileHierarchy = 'functions';
    end
    if userData.uiControl(dataDescription.enableTRCFileFXPSupport.uiControl).value,
       fxpSupport = 'yes';
    end
end

% make file options
if userData.uiControl(dataDescription.updateMakeFile.uiControl).value,
    updateMakeFile = 'yes';
else
    updateMakeFile = 'no';
end

% RTI code generation
if userData.uiControl(dataDescription.generatePPCApplication.uiControl).value,
    generatePPCApplication = 'yes';
else
    generatePPCApplication = 'no';
end
% get TL subsystems and corresponding destination blocks
uiCtrlAvailableTLSubsystems = dataDescription.availableTlSubsystemList.uiControl;
uiCtrlDestinationBlockList  = dataDescription.destinationBlockList.uiControl;
selectedTlSubsystems        = userData.uiControl(dataDescription.tlSubsystems.uiControl).value;

% CodeGenerationUnits
if userData.uiControl(dataDescription.enableDDCgUnitSelection.uiControl).value
    selectedDDCGUnits = userData.uiControl(dataDescription.ddCGUnits.uiControl).value;
else
    selectedDDCGUnits = {};
end

% find the corresponding destination blocks
[c,iA,iB]         = intersect(userData.uiControl(uiCtrlAvailableTLSubsystems).value, selectedTlSubsystems);          
[i,iB]            = sort(iB);
idx               = iA(iB);
destinationBlocks = userData.uiControl(uiCtrlDestinationBlockList).value(idx);

% Generate the stand-alone S-Function
tl_tl2rti('SrcModel'        ,srcModel,...
    'IncludeSubItems'       ,generateAll,...
    'GenerateGlobalSymbols' ,generateGlobalSymbols,...
    'DestModel'             ,destModel,...
    'DestBlocks'            ,destinationBlocks,...
    'TLSubsystems'          ,selectedTlSubsystems,...
    'DDCodeGenerationUnits' ,selectedDDCGUnits,...
    'GenerateTRC'           ,generateTRC,...
    'TRCFileHierarchy'      ,trcFileHierarchy,...
    'FixPointSupport'       ,fxpSupport,...
    'UpdateUsrMakeFile'     ,updateMakeFile,...
    'DestDirectory'         ,destDirectory,...
    'GeneratePPCApplication',generatePPCApplication);


userData.bApplyUiControls = 1;
userData.bApplyData       = 0;
userData.bClose           = 0;


%================================================================================
% private function to create the figure window
%================================================================================

function FcnCreate(hBlock)


% This dialog can be open only in full-featured mode
if strcmp(tl_get_blockset_mode, 'stand-alone')
    ds_error_msg({...
        'The Standalone Model Manager block is not available in stand-alone mode.',...
    });
    return;
end

% get the data description for all uicontrols
dataDescription = FcnGetDataDescription(hBlock);

descStr = {...
  'Create standalone S-Functions for the selected TargetLink subsystems and copy'...
  'them to the destination model for RCP code generation with dSPACE RTI.'...
};

% Create the property of the ds_generic_dlg
% NOTE: in case the list of the code generation units is empty do not open the CodeGenerationUnit window
dialogProperties = {...
   'FigureTag',            '#Fig_tl_tl2rti', ...
   'Title',                'Standalone Model Manager', ...
   'DataDescription',      dataDescription,...
   'BlockHandle',          hBlock, ...
   'FigureWidth',          400, ...
   'CallBackFcn',          mfilename, ...
   'FrameStructure',      {'frame1' 'frame2'},...
   ...
   'frame',                'frame1',...
   'Tag',                  'frame1',...
   'Style',                'frame',...
   'displayText',          'Targetlink Standalone Model Manager',...
   'frameWidth',           400, ...
   'uiStructure',          {'message'},...
   ...
   'Tag',                  'message', ...
   'Style',                'text', ...
   'MessageText',          descStr, ...
   ...
   'frame',                'frame2',...
   'Tag',                  'frame2',...
   'Style',                'frame',...
   'displayText',          'Parameters',...
   'frameWidth',           400, ...
   'uiStructure',          {{'destinationModel' 'Browse'} 'destinationDirectory' 'tlSubsystems' 'destinationBlock' 'generateForIncrSubsystems' 'generateGlobalSymbols' {'generateTRC' 'trcFileHierarchy'} 'enableTRCFileFXPSupport' 'updateMakeFile' 'generatePPCApplication'},...
   ...
   'Tag',                  'destinationModel', ...
   'Style',                'edit', ...
   'HeadLine',             'Destination model name', ...
   'uiControlWidth',        315,...
    ...
   'Tag',                  'Browse', ...
   'Style',                'pushbutton', ...
   'LabelStrings',         'Browse',...
   ...
   'Tag',                  'destinationDirectory', ...
   'Style',                'edit', ...
   'HeadLine',             'Destination model directory', ...
   'uiControlWidth',        385,...
   ...
   'Tag',                  'tlSubsystems', ...
   'Style',                'listbox', ...
   'DataStrings',          dataDescription.tlSubsystems.validValues,...  
   'HeadLine',             'Select TargetLink subsystem(s) to be converted', ...
   'uiControlSize',        [385,50],...
   ...
   'Tag',                  'destinationBlock', ...
   'Style',                'edit', ...
   'HeadLine',             'Destination block for selected TargetLink subsystem', ...
   'uiControlWidth',        385};
if ~isempty(dataDescription.ddCGUnits.validValues)
    dialogProperties = [dialogProperties {...
        'Tag',                  'enableDDCgUnitSelection', ...
        'Style',                'checkbox', ...
        'LabelStrings',         'Enable selection of the CodeGenerationUnit objects', ...
        'uiControlSize',        [385,0],...
        ...
        'Tag',                  'ddCGUnits', ...
        'Style',                'listbox', ...
        'DataStrings',          dataDescription.ddCGUnits.validValues,...
        ...'HeadLine',             'Select Data Dictionary CodeGenerationUnit(s)', ...
        'uiControlSize',        [385,50]}];
end
dialogProperties = [dialogProperties {...
   'Tag',                  'generateForIncrSubsystems', ...
   'Style',                'checkbox', ...
   'LabelStrings',         'Include sub-items for code generation', ... 
   'uiControlSize',        [200,0],...
   ...
   'Tag',                  'generateGlobalSymbols', ...
   'Style',                'checkbox', ...
   'LabelStrings',         'Create definitions for extern global interface variables', ... 
   'uiControlSize',        [200,0],...
   ...
   'Tag',                  'generateTRC', ...
   'Style',                'checkbox', ...
   'LabelStrings',         'Generate TRC file, show hierarchy of', ... 
   'uiControlSize',        [200,0],...
   ...
   'Tag',                  'trcFileHierarchy',...
   'Style',                'popupmenu',...
   'uiControlSize',        [180,0],...
   ...
   'Tag',                  'enableTRCFileFXPSupport', ...
   'Style',                'checkbox', ...
   'LabelStrings',         'Enable TRC file Generator''s fix point data support', ...
   'uiControlSize',        [385,0],...
   ...
   'Tag',                  'updateMakeFile', ...
   'Style',                'checkbox', ...
   'LabelStrings',         'Update USR makefile for dSPACE RTI', ...
    ...
   'Tag',                  'generatePPCApplication', ...
   'Style',                'checkbox', ...
   'LabelStrings',         'Generate PPC application using dSPACE RTI', ...
    ...
   'ButtonName',           'OK', ...
   'ButtonName',           'Cancel', ...
   'ButtonName',           'Help', ...
   'ButtonName',           'Apply', ...
   'ButtonName',           'Build',...
   'DefaultButton',        'OK'}];

userData = ds_generic_dlg('Create', dialogProperties{:});

% if no TL subsystem in model, disable the parameters frame and the Build-Button
if isempty(userData.dataDescription.tlSubsystems.defaultValue),
   uiControlList = {
       'destinationModel'
       'tlSubsystems'
       'enableDDCgUnitSelection'
       'ddCGUnits'
       'destinationBlock'
       'generateTRC'
       'trcFileHierarchy'
       'enableTRCFileFXPSupport'
       'updateMakeFile'
       'destinationDirectory'
       'generatePPCApplication'
       'generateForIncrSubsystems'
       'generateGlobalSymbols'
   };
   for m=1:length(uiControlList),
       uiControlDescription = userData.dataDescription.(uiControlList{m});
       handle = userData.uiControl(uiControlDescription.uiControl).handle;
       if(handle == -1)
           % Can happen if uicontrol does not exists.
           % This can apply for enableDDCgUnitSelection and ddCGUnits
           continue;
       end
       set(handle, 'Enable','off');
   end
   
   hBuild = userData.buttonData(5).handle;
   set(hBuild, 'Enable','off');
   
   hBrowse = userData.buttonData(6).handle;
   set(hBrowse, 'Enable','off');
   return;
end

% Check the value of the enableDDCGUnitSelection checkbox. If needed disable the ddCGUnitSelection


%-----------------------------------------------------------
% private function returning a description of the block data
%-----------------------------------------------------------

function [dataDescription, varargout] = FcnGetDataDescription(hBlock)


% get the list of all available tlSubsystems
model                = get_param(bdroot(hBlock),'Name');
tlSubsystems         = get_tlsubsystems(model);
bTLSubsystemExist    = 0;
if isempty(tlSubsystems),
   tlSubsystemNames  = {''};
else
   bTLSubsystemExist = 1;
   tlSubsystemNames  = cellstr(get_param(tlSubsystems,'Name'));
end

% Get the list of all available DD CG Units
[tmp, ddCGUnitNames] = tl_get_ddcgunits;

% list of all callback actions
dataDescription.callBackActions = {
   'create'
   'sync'
   'apply'
   'help'
   'build'
   'browse'
   'getdatadescription'
};

% list of all property names
dataDescription.propertyNames = {
   'revisionNumber'
   'destinationModel'
   'destinationDirectory'
   'tlSubsystems'
   'enableDDCgUnitSelection'
   'ddCGUnits'
   'destinationBlock'
   'availableTlSubsystemList'
   'destinationBlockList'
   'generateTRC'
   'trcFileHierarchy'
   'enableTRCFileFXPSupport'
   'updateMakeFile'
   'generatePPCApplication'
   'generateForIncrSubsystems'
   'generateGlobalSymbols'
};

% revisionNumber
dataDescription.revisionNumber.dataType             = 'integer';
dataDescription.revisionNumber.validValues          = [];
dataDescription.revisionNumber.defaultValue         = 4;
dataDescription.revisionNumber.attributes           = {'read-only','hidden'};

% edit: destination model 
dataDescription.destinationModel.dataType           = 'string';
dataDescription.destinationModel.validValues        = [];
dataDescription.destinationModel.defaultValue       = [model '_standalone'];
if length(dataDescription.destinationModel.defaultValue ) > namelengthmax,
   dataDescription.destinationModel.defaultValue = 'StandaloneModel';
end
dataDescription.destinationModel.attributes         = {};

% edit: destination directory 
dataDescription.destinationDirectory.dataType       = 'string';
dataDescription.destinationDirectory.validValues    = [];
dataDescription.destinationDirectory.defaultValue   = pwd;
dataDescription.destinationDirectory.attributes     = {};

% listbox: TL subsystems
dataDescription.tlSubsystems.dataType               = 'string vector';
dataDescription.tlSubsystems.validValues            = tlSubsystemNames;
dataDescription.tlSubsystems.defaultValue           = tlSubsystemNames{1};
dataDescription.tlSubsystems.attributes             = {'never-save'};

% checkbox: enable DD CGUnit selection 
dataDescription.enableDDCgUnitSelection.dataType     = 'integer';
dataDescription.enableDDCgUnitSelection.validValues  = [0 1];
dataDescription.enableDDCgUnitSelection.defaultValue = 1;
dataDescription.enableDDCgUnitSelection.attributes   = {};

% listbox: DD CGUnits
dataDescription.ddCGUnits.dataType               = 'string vector';
dataDescription.ddCGUnits.validValues            = ddCGUnitNames;
if isempty(ddCGUnitNames)
    dataDescription.ddCGUnits.defaultValue = '';
else
    dataDescription.ddCGUnits.defaultValue = ddCGUnitNames{1};
end
dataDescription.ddCGUnits.attributes             = {'never-save'};


% edit field: destinationBlock
dataDescription.destinationBlock.dataType           = 'string';
dataDescription.destinationBlock.validValues        = [];
if bTLSubsystemExist,
    dataDescription.destinationBlock.defaultValue   = [model '/' tlSubsystemNames{1}];
else
    dataDescription.destinationBlock.defaultValue   = '';
end
dataDescription.destinationBlock.attributes         = {};


% no uiControl: availableTlSubsystemList
dataDescription.availableTlSubsystemList.dataType     = 'string';
dataDescription.availableTlSubsystemList.validValues  = [];
dataDescription.availableTlSubsystemList.defaultValue = tlSubsystemNames;
dataDescription.availableTlSubsystemList.attributes   = {};


% no uiControl: destinationBlockList
dataDescription.destinationBlockList.dataType        = 'string';
dataDescription.destinationBlockList.validValues     = [];
if bTLSubsystemExist,
   for i=1:length(tlSubsystemNames),
      dataDescription.destinationBlockList.defaultValue{i} = [model '/' tlSubsystemNames{i}];
   end
else
   dataDescription.destinationBlockList.defaultValue = {''};
end
dataDescription.destinationBlockList.attributes      = {};


% checkbox: generateTRC
dataDescription.generateTRC.dataType                = 'integer';
dataDescription.generateTRC.validValues             = [0 1];
dataDescription.generateTRC.defaultValue            = 1;
dataDescription.generateTRC.attributes              = {};

% listbox: trcFileHirarchy
dataDescription.trcFileHierarchy.dataType           = 'string';
% dataDescription.trcFileHierarchy.validValues        = {'Simulink subsystems                    ' 'generated functions'};
% dataDescription.trcFileHierarchy.defaultValue       = 'Simulink subsystems                    ';
dataDescription.trcFileHierarchy.validValues        = {'Simulink subsystems' 'generated functions'};
dataDescription.trcFileHierarchy.defaultValue       = 'Simulink subsystems';
dataDescription.trcFileHierarchy.attributes         = {};

% checkbox: enable TRC file's fix point support 
dataDescription.enableTRCFileFXPSupport.dataType     = 'integer';
dataDescription.enableTRCFileFXPSupport.validValues  = [0 1];
dataDescription.enableTRCFileFXPSupport.defaultValue = 1;
dataDescription.enableTRCFileFXPSupport.attributes   = {};

% checkbox: updateMakeFile
dataDescription.updateMakeFile.dataType             = 'integer';
dataDescription.updateMakeFile.validValues          = [0 1];
dataDescription.updateMakeFile.defaultValue         = 1;
dataDescription.updateMakeFile.attributes           = {};

% checkbox: generatePPCApplication
dataDescription.generatePPCApplication.dataType     = 'integer';
dataDescription.generatePPCApplication.validValues  = [0 1];
dataDescription.generatePPCApplication.defaultValue = 0;
dataDescription.generatePPCApplication.attributes   = {};

% checkbox: generate code for incremental subsystems
dataDescription.generateForIncrSubsystems.dataType     = 'integer';
dataDescription.generateForIncrSubsystems.validValues  = [0 1];
dataDescription.generateForIncrSubsystems.defaultValue = 0;
dataDescription.generateForIncrSubsystems.attributes   = {};

% checkbox: generate definitions for global symbols
dataDescription.generateGlobalSymbols.dataType     = 'integer';
dataDescription.generateGlobalSymbols.validValues  = [0 1];
dataDescription.generateGlobalSymbols.defaultValue = 1;
dataDescription.generateGlobalSymbols.attributes   = {};

if nargout > 1,
    varargout{1} = tlSubsystemNames;
end


%======================================================================================================
%
% FcnManageControlsConsistency - private function to manage the controls consistency
%
%======================================================================================================
function userData = FcnManageControlsConsistency(userData)

% If dialog is open take the dataDescritpion from the userData !
% Otherwise the controls Ids may change if for example
% a new TL Subsystem has been added !
dataDescription = userData.dataDescription;

if isempty(dataDescription.tlSubsystems.defaultValue),
    % all controls are disabled 
    return;
end

% check the value for destination model 
destModel = userData.uiControl(dataDescription.destinationModel.uiControl).value;
if ~ischar(destModel) || isempty(destModel)
    userData.uiControl(dataDescription.destinationModel.uiControl).value = ...
        userData.uiControl(dataDescription.destinationModel.uiControl).prevValue;
elseif ~ds_regexp('[a-zA-Z]+[_a-zA-Z0-9]*',destModel) || length(destModel) > namelengthmax,
    userData.uiControl(dataDescription.destinationModel.uiControl).value = ...
        userData.uiControl(dataDescription.destinationModel.uiControl).prevValue;
end

% check the value for the destination directory, it cannot be empty and without ''
% at the end
destDirectory = userData.uiControl(dataDescription.destinationDirectory.uiControl).value;
if isempty(destDirectory),
   userData.uiControl(dataDescription.destinationDirectory.uiControl).value = ...
      userData.uiControl(dataDescription.destinationDirectory.uiControl).prevValue;
end
  

% synchronize the entry in destination block edit field and in destination block list
userData = FcnManageDestinationBlock(userData);

% enable trcFileHierarchy only if generateTRC has been selected
if userData.uiControl(dataDescription.generateTRC.uiControl).value,
    userData.uiControl(dataDescription.trcFileHierarchy.uiControl).bEnabled = 1;
else
    userData.uiControl(dataDescription.trcFileHierarchy.uiControl).bEnabled = 0;
end

% Enable CGUnit selection if desired
if userData.uiControl(dataDescription.enableDDCgUnitSelection.uiControl).value,
    userData.uiControl(dataDescription.ddCGUnits.uiControl).bEnabled = 1;
else
    userData.uiControl(dataDescription.ddCGUnits.uiControl).bEnabled = 0;
end

%======================================================================================================
%
% FcnManageDestinationBlock - private function to set the destination block for specified tlSubsystem
%
%======================================================================================================
function userData = FcnManageDestinationBlock(userData)

% get the data description
dataDescription = userData.dataDescription;

% get handles and uiControls ids
uiCtrlAvailableTLSubsystems = dataDescription.availableTlSubsystemList.uiControl;
uiCtrlDestBlockList         = dataDescription.destinationBlockList.uiControl;
uiCtrlDestinationBlock      = dataDescription.destinationBlock.uiControl;

% Get the selectet TL-Subsystems and the list of all available TL Subsystems
% Find the selected TL subsystems in the list of all TL subsystems
selectedTLSubsystem   = cellstr( userData.uiControl(userData.dataDescription.tlSubsystems.uiControl).value);
availableTlSubsystems = userData.uiControl(uiCtrlAvailableTLSubsystems).value;

if length(selectedTLSubsystem) ~= 1,
    % disable the destination block edit field, nothing more to do !
    userData.uiControl(uiCtrlDestinationBlock).value = '';
    userData.uiControl(uiCtrlDestinationBlock).bEnabled = 0;
    return;
end

% If the current uiControl is the destination block edit field
% up to date the corresponding entry in the destinationBlockList
% Ensure that the model specification in the destination block path
% is the same as the destination model !
idx = find(strcmp(selectedTLSubsystem, availableTlSubsystems));
if userData.currentUiControl == dataDescription.destinationBlock.uiControl,
    userData.uiControl(uiCtrlDestBlockList).value{idx} = userData.uiControl(uiCtrlDestinationBlock).value;
end
% synchronize the destination model and the destination blocks
destModel = userData.uiControl(dataDescription.destinationModel.uiControl).value;
for i=1:length(userData.uiControl(uiCtrlDestBlockList).value),
   [prevDestModel, block] = strtok(userData.uiControl(uiCtrlDestBlockList).value{i} ,'/');
   userData.uiControl(uiCtrlDestBlockList).value{i} = [destModel block];
end

% enable the destination block edit field and set the appropriate destination block
userData.uiControl(uiCtrlDestinationBlock).value    = userData.uiControl(uiCtrlDestBlockList).value{idx};
userData.uiControl(uiCtrlDestinationBlock).bEnabled = 1;

%======================================================================================================
%
% FcnSyncTLSubsystems - private function to synchronizing the tlSubsystems uiControl with the
%                      currently available TL Subsystems
%                              
%======================================================================================================

function userData = FcnSyncTLSubsystems(userData)

% get the data decsriptiom
dataDescription = userData.dataDescription;

% get the valid TlSubsystem names
tlSubsystemNameList = cellstr(dataDescription.tlSubsystems.validValues);

% from the list of selected TL Subsystems, remove these ones, which are not valid
uiCtrlTlSubsystems      = dataDescription.tlSubsystems.uiControl;
selectedTLSubsystemList = cellstr(userData.uiControl(uiCtrlTlSubsystems).value);
userData.uiControl(uiCtrlTlSubsystems).value = cellstr(userData.uiControl(uiCtrlTlSubsystems).value);
[names, idx] = setdiff(selectedTLSubsystemList,tlSubsystemNameList);
userData.uiControl(uiCtrlTlSubsystems).value(idx) = [];
if isempty(userData.uiControl(uiCtrlTlSubsystems).value),
   userData.uiControl(uiCtrlTlSubsystems).value = tlSubsystemNameList{1};
end


%======================================================================================================
%
% FcnSyncDestinationBlockList - private function to synchronizing the list of destination blocks 
%                              
%======================================================================================================

function userData = FcnSyncDestinationBlockList(userData)

dataDescription = userData.dataDescription;

% get the valid TlSubsystem names
tlSubsystemNameList = cellstr(dataDescription.tlSubsystems.validValues);

% in the destinationBlockList, find these destination blocks which does not correspond
% to any of the valid TL subsystems and remove them
uiCtrlAvailableTLSubsystems = dataDescription.availableTlSubsystemList.uiControl;
uiCtrlDestBlockList         = dataDescription.destinationBlockList.uiControl;
uiCtrlDestModel             = dataDescription.destinationModel.uiControl;
availableTlSubsystems       = userData.uiControl(uiCtrlAvailableTLSubsystems).value;
[diffNameList, diffIds]     = setdiff(availableTlSubsystems, tlSubsystemNameList);
userData.uiControl(uiCtrlAvailableTLSubsystems).value(diffIds) = [];
userData.uiControl(uiCtrlDestBlockList).value(diffIds)         = [];

% now check which new tlSubsystem are added and append them to the destinationBlockList
[diffNameList, diffIds] = setdiff(tlSubsystemNameList, availableTlSubsystems); 
userData.uiControl(uiCtrlAvailableTLSubsystems).value = cellstr(userData.uiControl(uiCtrlAvailableTLSubsystems).value);
userData.uiControl(uiCtrlDestBlockList).value         = cellstr(userData.uiControl(uiCtrlDestBlockList).value);
for i=1:length(diffIds),
    userData.uiControl(uiCtrlAvailableTLSubsystems).value{end+1} = diffNameList{i};
    userData.uiControl(uiCtrlDestBlockList).value{end+1}         = [userData.uiControl(uiCtrlDestModel).value '/' diffNameList{i}];
end
 


%======================================================================================================
%
% FcnSetDestinationModel - private function to set destination model name and directory, if empty 
%                              
%======================================================================================================
function  userData = FcnSetDestinationModel(userData)

dataDescription = userData.dataDescription;

% check if destination model name and directory are empty
uiControlDestModelName = dataDescription.destinationModel.uiControl;
uiCintrolDestModelDir  = dataDescription.destinationDirectory.uiControl;
if isempty(userData.uiControl(uiControlDestModelName).value),
   userData.uiControl(uiControlDestModelName).value = dataDescription.destinationModel.defaultValue;
end
if isempty(userData.uiControl(uiCintrolDestModelDir).value),
   userData.uiControl(uiCintrolDestModelDir).value = dataDescription.destinationDirectory.defaultValue;
end
